#include "stdafx.h"
#include "SomeContainer.h"
#include "IObject.h"
#include "SomeContainterIterator.h"

CSomeContainer::CSomeContainer()
: m_head(NULL)
{
}

CSomeContainer::~CSomeContainer()
{
}

bool CSomeContainer::Register(int objectId, boost::shared_ptr<IObject> object)
{
    if (Query(objectId).get() != NULL)
    {
        return false;
    }

    Node* newNode = NULL;
    Node* left = NULL;
    do
    {
        boost::shared_ptr<Node> ptr(m_head.load());
        newNode = new Node(object, objectId, ptr);
        left = newNode->next.get();
    } while(!m_head.compare_exchange_weak(left, newNode));

    return true;
}

bool CSomeContainer::Unregister(int objectId)
{
    if (m_head.load() == NULL)
    {
        return false;
    }

    Node* oldHead = m_head.load();
    if (m_head.load()->index == objectId)
    {
        oldHead = m_head.load();
    }
    else
    {
        while (oldHead && oldHead->next.get() && oldHead->next->next.get() && oldHead->next->index != objectId)
        {
            oldHead = oldHead->next.get();
        }
        if (oldHead && oldHead->next && oldHead->next->index != objectId)
        {
            return false;
        }
    }
    
    if (oldHead->next.get() && oldHead->index != objectId)
    {
        boost::atomic<boost::shared_ptr<Node>> oldHeadAtomic(oldHead->next->next);
        // here problem
        while(oldHead && oldHead->next && !oldHeadAtomic.compare_exchange_weak(oldHead->next, oldHead->next->next));
    }
    else if(m_head.load() == oldHead && m_head.load()->index == objectId)
    {
        while(oldHead && !m_head.compare_exchange_strong(oldHead, oldHead->next.get()));
    }
    else
    {
        boost::atomic<Node*> oldHead_atomic(oldHead->next.get());
        while(oldHead && !oldHead_atomic.compare_exchange_strong(oldHead, oldHead->next.get()));
    }
    
    return true;
}

boost::shared_ptr<IObject> CSomeContainer::Query(int objectId)
{
    Node* oldHead = m_head.load();
    while (oldHead)
    {
        if (oldHead->index == objectId)
        {
            return oldHead->data;
        }
        oldHead = oldHead->next.get();
    }
    
    IObject* p = NULL;
    return boost::shared_ptr<IObject>(p);
}

std::auto_ptr<ISomeContainterIterator> CSomeContainer::CreateIterator()
{
    return std::auto_ptr<ISomeContainterIterator>(new CSomeContainterIterator(this));
}